/**
 * This file is part of the flushOS project.
 *
 * Copyright (C) 2007 Alexander Blessing
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 */

#include <types.h>
#include <string.h>

/**              **
 * Misc functions *
 **              **/

/* Convert an integer to string */

void itoa(uint32_t n, char *s, int8_t base)
{
	uint32_t i, j;
	char tmp[20], digit;

	i = 0;
	do
	{
		j = n;
		n /= base;	/* divide num by base */
		n *= base;	/* multiply num by b to isolate the digit */
		digit = j - n;

		/* change the numerical digit to printable ASCII value */
		if(digit <= 9)
		{
			tmp[i] = digit + '0';
		}
		else
		{
			tmp[i] = digit - 0x0A + 'A';
		};
		n /= base;	/* divide num by b again to get to the next digit */
		i++;
	} while(n != 0);

	tmp[i] = '\0';	/* add the terminator */

	/* reverse string */
	j = strlen(tmp) - 1;
	for (i = 0; i < strlen(tmp); i++) {
		s[i] = tmp[j];
		j--;
	}
	s[i] = '\0';
}

/**                        **
 * String related functions *
 **                        **/

//Returns the length of a string
size_t strlen(char* str)
{
	size_t i = 0;

	while(str[i] != '\0')
		i++;

	return i;
}

//Compares two strings
int strcmp(const char *s1, const char *s2)
{
	for (; *s1 == *s2; s1++, s2++)
		if (*s1 == '\0')
			return 0;	/* equal */
	return *s1 - *s2;
}

//Compares first 'n' characters of two strings
int strncmp(const char *s1, const char *s2, size_t n)
{
	uint16_t i = 1;

	for (; *s1 == *s2 && i <= n; s1++, s2++, i++)
		if (i == n)
			return 0;	/* equal */
	return *s1 - *s2;
}

/* Copies two strings */
char *strcpy(char *dest, const char *src)
{
	while (*src != '\0')
		*(dest++) = *(src++);

	return dest;
}

/* Copies two strings max 'n' characters */
char *strncpy(char *dest, const char *src, size_t n)
{
	const char *s = src;
	char *d = dest;

	while (*s != '\0' && n-- > 0)
		*(d++) = *(s++);

	return dest;
}

/* Concatenates two strings */
char *strcat(char *dest, const char *src)
{
	char *s = dest;

	while(*(s++) != '\0')

	while(*src != '\0')
		*(s++) = *(src++);
	*s = '\0';

	return dest;
}

/* Concatenates two strings max 'n' characters */
char *strncat(char *dest, const char *src, size_t n)
{
	char *s = dest;

	for (; *s != '\0'; s++)
		;
	while (*src != '\0' && n-- > 0)
		*(s++) = *(src++);
	*s = '\0';

	return dest;
}

/**                        **
 * Memory related functions *
 **                        **/

/* Copies 'n' bytes from 'src' to 'dest' */
void *memcpy(void *dest, const void *src, size_t n)
{
	char *to = (char *) dest;
	char *from = (char *) src;

	while(n-- > 0)
		*(to++) = *(from++);

	return dest;
}

/* Fills the first 'n' bytes with 'c' */
void *memset(void *s, const int c, size_t n)
{
	char *to = (char*) s;

	while (n-- > 0)
		*(to++) = c;
	return s;
}
